#ifndef PARTICLE_COLLECTION
#define PARTICLE_COLLECTION


#include <vector>
#include <glm\glm.hpp>

//For defining a particle to add.
struct ParticleDef {
	glm::vec3 pos;
	glm::vec3 vel;
	float mass;
};

class ParticleCollection;


class ParticleIter {
	friend ParticleCollection;

public:
	ParticleIter();

	ParticleIter(ParticleCollection *);

	const glm::vec3 & cPos() const;

	const glm::vec3 & cVel() const;

	glm::vec3 & force();

	glm::vec3 & pos();

	glm::vec3 & prevAccel();

	unsigned int GetNdx() const { return ndx; }

	const float & cMass() const;

	float & mass();

	glm::vec3 & vel();

	//XXX Probably inefficient
	float & operator [] (const int & i ) {
		return pos()[i];
	}

	const float & operator [] (const int & i) const {
		return this->cPos()[i];
	}

	//Prefix operators
	ParticleIter & operator++ ();
	ParticleIter & operator-- ();

	//Postfix operators
	ParticleIter operator++ (int);
	ParticleIter operator-- (int);

	bool operator!= (const ParticleIter & rhs) const;
	
private:

	ParticleCollection * collection;
	unsigned int ndx;
};

//Holds a set of particles.
class ParticleCollection {
public:

	void Insert( const ParticleDef & inPart );

	void Remove( unsigned int partNum );

	ParticleIter Begin();

	unsigned int Size();

	ParticleIter End();

	ParticleIter operator[] ( unsigned int i );

protected:
	friend ParticleIter;

	//Positions
	std::vector< glm::vec3 > mPos;

	//Masses
	std::vector< float > mMass;

	//Forces
	std::vector< glm::vec3 > mF;

	//Vel
	std::vector< glm::vec3 > mVel;

	std::vector < glm::vec3 > mPrevAccel;
};



#endif